home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
-
- use Getopt::Long;
-
- #----------------------------------------------------------------------------
-
- $h_minfreq = 30000; ## Mininum scan frequency
- $h_maxfreq = 35500; ## Maximum scan frequency
- $maxdot = 70000000; ## Maximum dot clock frequency (Hz)
-
- $h_freq_error = 0.991; ## Margin for hsync adjustments
- $h_extra_space = 1.27; ## Extra Horizontal space factor
- $v_extra_space = 0.93; ## Extra Vertical space factor
- $h_sync1_guess = 80; ## Horizontal sync1 guess
- $h_sync2_guess = 80; ## Horizontal sync2 guess
-
- #----------------------------------------------------------------------------
-
- ### Check command line ###
-
- $Cmd_font = "8x16"; ## Default Font specification
- $Cmd_vsf = 60; ## Default Vertical Frequency.
- $Cmd_help = 0;
- $Cmd_dotclock = 0;
- $Cmd_verbose = 0;
- $Cmd_trick9 = 0;
-
- $ret = GetOptions("help", \$Cmd_help,
- "font:s", \$Cmd_font,
- "vsf:i", \$Cmd_vsf,
- "dot:f", \$Cmd_dotclock,
- "verbose", \$Cmd_verbose,
- "trick9", \$Cmd_trick9,
- "hmargin:f", \$h_extra_space,
- "vmargin:f", \$v_extra_space);
-
- if ($ARGV[0] eq "" || $Cmd_help || $ret == 0 || $Cmd_vsf == 0)
- {
- print STDERR "Usage: SVGATextCalc <mode> [--font=fontspec] [--trick9] [--verbose]\n";
- print STDERR " [--vsf=refresh(Hz)] [--dot=dotclock(MHz)]\n";
- print STDERR " [--hmargin=factor] [--vmargin=factor]\n";
- exit 1;
- }
-
- ($font_width, $font_height) = split('x', $Cmd_font);
- ($h_text_lines, $v_text_lines) = split(/x/,$ARGV[0]);
- $v_freq = $Cmd_vsf;
-
-
- ### Grab allowed ranges from /etc/Textconfig ###
- ($h_minfreq, $h_maxfreq, $maxdot) = getlimits();
-
- if ($Cmd_verbose) {
- print "Horizontal Frequency: $h_minfreq, $h_maxfreq, Maximum dot=$maxdot\n";
- }
-
- #-----------------------------------------------------------------------------
-
- ### Check horizontal frequency ###
-
- $v_lines = $font_height * $v_text_lines / $v_extra_space;
- $h_freq = $v_lines * $v_freq;
-
- ### I control the vertical... ###
-
- $v_res = round($font_height, $v_lines * $v_extra_space); ## Vertical resolution
- $v_start = $v_res; ## Vertical start
- $v_end = $v_start + $font_height; ## Vertical end
-
- ### ...And the Horizontal ###
-
- $h_pixels = round(8, $h_text_lines * $font_width * $h_extra_space);
- $h_res = round(8, $h_text_lines * $font_width);
- $pixelclock = $h_pixels * $h_freq;
- $h_start = round(8, $h_res + $h_sync1_guess);
- $h_end = round(8, $h_start + $h_sync2_guess);
-
- ##
- ## We must make every effort so that the user must make as few
- ## adjustments as possible in the output. If the user didn't
- ## specify a fixed dotclock and our horizontal frequency is out
- ## of scale, we then recalculate the dotclock so that the frequency
- ## will be as close as possible to the offending bound (either
- ## upper or lower).
- ##
- ## The code below only recalculates the new clock and puts it
- ## into the variable $Cmd_dotclock.
- ##
-
- if (! $Cmd_dotclock)
- {
- ##
- ## We adjust the frequency to the maximum or minimum
- ## allowed, and then generate the new dotclock to
- ## keep things "balanced".
- ##
-
- if ($h_freq < $h_minfreq || $h_freq > $h_maxfreq)
- {
- if ($h_freq < $h_minfreq) { $newclock = $h_minfreq * (1+(1-$h_freq_error)) * $h_pixels; }
- else { $newclock = $h_maxfreq * $h_freq_error * $h_pixels; }
- }
-
- $Cmd_dotclock = $newclock / 1000000;
- }
-
- ##
- ## If we have a fixed dot clock request (either by the means of the --dot
- ## command line switch or set by the piece of code above), we must recalc
- ## the parameters to keep the screen in sync. There's no guarantee that
- ## the resolution will be the same (remember, the asked one may not be
- ## possible at all), but the program will make its best to make it close.
- ##
-
- if ($Cmd_dotclock)
- {
- ### Calculate multiplying factor to the new dotclock ###
-
- $h_divfactor = ($Cmd_dotclock * 1000000) / $pixelclock;
-
- ##
- ## First, we check if the new HSF (changed with the new dotclock) still
- ## fits our range. If so, then we have a deal, and keep the new dotclock without
- ## a change on the expected resolution. Otherwhise, we have to hack the
- ## horizontal parameters to make it fit. Of course, that will change the
- ## number of characters on the line, but that's the way it is...
- ##
-
- $h_freq_new = $h_freq * $h_divfactor;
-
- if ($h_freq_new >= $h_minfreq && $h_freq_new <= $h_maxfreq)
- {
- $h_freq = $h_freq_new;
- }
- else
- {
- $h_res = round(8, $h_res * $h_divfactor);
- $h_start = round(8, $h_start * $h_divfactor);
- $h_end = round(8, $h_end * $h_divfactor);
- $h_pixels = round(8, $h_pixels * $h_divfactor);
- }
-
- $pixelclock = $Cmd_dotclock * 1000000;
- }
-
- ##
- ## Check the 9 pixels spacing trick
- ## This uses a feature on the VGA to add spacing between characters.
- ## Everything must be calculated as if we were using 8 pixel fonts, though.
- ##
- ## The reported dotclock may not be the same as set with the --dot command line.
- ## This feature is best explained in SVGATextMode documentation.
- ##
-
- if ($Cmd_trick9 && $font_width == 8)
- {
- $pixelclock = $pixelclock * 9 / 8;
- $font_width = 9;
- }
-
- if ($Cmd_verbose)
- {
- printf STDERR "Resolution: %dx%d chars, ", $h_text_lines, $v_text_lines;
- printf STDERR "font: %dx%d pixels, ", $font_width, $font_height;
- printf STDERR "VSF=%d Hz, HSF=%.2f KHz\n", $h_freq / $v_lines, $h_freq/1000;
- }
-
- ### Sanity checks ###
-
- if ($h_freq < $h_minfreq || $h_freq > $h_maxfreq)
- {
- print STDERR "\n*** WARNING: Horizontal frequency is out of range ***\n\n";
- }
-
- if ($pixelclock > $maxdot)
- {
- print STDERR "\n*** WARNING: Dotclock is out of range ***\n\n";
- }
-
- ### Print the results ###
-
- printf "# Generated by SVGATextCalc (paganini\@ism.com.br), %dHz, %.2fKHz\n" ,$h_freq/$v_lines, $h_freq/1000;
- printf "\"T%dx%dx%d\" %02.2f %4.4s %4.4s %4.4s %4.4s %4.4s %4.4s %4.4s %4.4s font %dx%d # %dHz/%.2fKHz\n" ,
- int($h_res / (($Cmd_trick9) ? 8 : $font_width)),
- int($v_res / $font_height),
- $font_width,
- $pixelclock/1000000,
- int($h_res), int($h_start), int($h_end), int($h_pixels),
- int($v_res), int($v_start), int($v_end), int($v_lines),
- $font_width, $font_height,
- $h_freq/$v_lines, $h_freq/1000;
-
- exit(0);
-
- #----------------------------------------------------------------------------------------
-
- sub getlimits
- {
- my($lowfreq, $hifreq, $dacspeed);
-
- if (! open (CFG, "/etc/TextConfig"))
- {
- print "Error opening /etc/TextConfig. Is SVGATextMode installed?\n";
- exit 1;
- }
-
- while (<CFG>)
- {
- if (m/^HorizSync[ \t]*(.*)/o)
- {
- @freqs = split(/[,-]/,$1);
- $lowfreq = $freqs[0] * 1000;
- $hifreq = $freqs[$#freqs] * 1000;
- }
- elsif (m/^DacSpeed[ \t]*([0-9]+)/o)
- {
- $dacspeed = $1 * 1000000;
- }
- }
-
- if ($hifreq == 0 || $lowfreq == 0)
- {
- print STDERR "I need the HorizSync line in /etc/TextConfig.\n";
- exit 1;
- }
-
- if ($dacspeed == 0 || $lowfreq == 0)
- {
- print STDERR "I need the DacSpeed line in /etc/TextConfig.\n";
- exit 1;
- }
-
- return ($lowfreq, $hifreq, $dacspeed);
- }
-
- #----------------------------------------------------------------------------------------
- sub round
- {
- my($factor, $val) = @_;
- return int($val / $factor) * $factor;
- }
-